<?php

namespace App\Service\ChatGroup;

use App\Exceptions\BotException\WhoBotException;
use App\Library\FeiShu\SendFs;
use App\Models\ChatGroup\ChatGroupFAQModel;
use App\Models\ChatGroup\ChatGroupHistoryModel;
use App\Models\ChatGroup\ChatGroupSessionModel;
use App\Models\ChatGroup\ChatGroupUserModel;
use App\Models\Common\ConfigModel;
use App\Service\ChatGroup\AiBot\BotClient;
use App\Service\OpenShop\Feishu\MessageSendService;
use Exception;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Kuafu\GeneralFs\BuildFs;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class ChatGroupAiChatService
{
    const QUEUE_NAME = '{chat-ai-bot}';

    // 队列等待时间
    const DELAY_TIME = 5;

    // 消息合并时间
    const MESSAGE_MERGE_TIME = 5;

    private $lastMsgInfo;


    /**
     */
    public function __construct(int $lastMessageId)
    {
        $this->lastMsgInfo = ChatGroupHistoryModel::query()
                                                  ->where('id', $lastMessageId)
                                                  ->first();
    }


    public function getLastMsgInfo()
    {
        return $this->lastMsgInfo;
    }

    /**
     * AI 对话 JOB
     *
     * @param int $messageId
     * @param int $groupId
     * @param int $shopId
     * @return void
     * @throws Exception
     */
    public static function chatMsgJob(
        int $messageId,
        int $groupId,
        int $shopId
    ) {

        Log::info('BOT_AI:chatMsgJob', [
            'messageId' => $messageId,
            'groupId'   => $groupId,
            'shopId'    => $shopId
        ]);
        dispatch(function () use ($messageId, $groupId, $shopId) {
            try {
                // message ai 请求
                $chatGroupAiChatService = new ChatGroupAiChatService($messageId);
                $result                 = $chatGroupAiChatService->chat();

                // 非最新消息, 结束对话
                if (!$result['isChat']) {
                    return;
                }

                $chatResult = $result['data'];

                // 人工介入
                if ($chatResult['to_human'] == 1) {
                    ChatGroupAiChatService::callServe($shopId, $groupId);
                    return;
                }

                // 非答案回复
                if ($chatResult['order_status'] != 'Completed') {
                    // 直接聊天
                    ChatGroupAiChatService::aiSendMsg($groupId, ChatGroupHistoryModel::TYPE_TEXT,
                        $chatResult['response']);
                    return;
                }

                // 答案回复
                $indexAnswer = $chatResult['response'];

                // 通过 indexAnswer 获取答案
                $answer = ChatGroupFAQModel::getAnswerByIndex($indexAnswer);

                // 答案为空 直接唤起人工
                if (empty($answer)) {
                    throw new Exception('答案不存在, 答案索引为:' . $indexAnswer);
                }

                // 发送答案
                ChatGroupAiChatService::sendQuestionAnswer($answer, $groupId, true);

            } catch (WhoBotException $botException) {
                Log::error('BOT_AI:WhoBotException', ['exceptionAll' => $botException]);
                // 机器人报错, 用飞书机器人推送出来
                BuildFs::newRobot(SendFs::ROBOT_WHO_BOT_AI_ERROR)
                       ->setTitleContent("呼博特机器人请求异常", $botException->getMessage())
                       ->send();
                // 任何异常 强制唤起人工处理
                ChatGroupAiChatService::callServe($shopId, $groupId);

            } catch (\Exception $exception) {
                Log::error('BOT_AI:Exception', ['exceptionAll' => $exception]);
                // 任何异常 强制唤起人工处理
                BuildFs::newRobot(SendFs::ROBOT_WHO_BOT_AI_ERROR)
                       ->setTitleContent("AI 消息队列 异常", $exception->getMessage())
                       ->send();
                ChatGroupAiChatService::callServe($shopId, $groupId);

                return;
            }
        })->delay(ChatGroupAiChatService::DELAY_TIME) // x秒后请求 AI 处理
          ->onQueue(ChatGroupAiChatService::QUEUE_NAME);
    }


    /**
     * 对话聊天
     *
     * @return array
     */
    public function chat(): array
    {
        $aiBot = BotClient::instance();

        // 校验是否是最新的消息
        $isLastMessage = ChatGroupHistoryService::checkIsLastMessage($this->lastMsgInfo);

        if (!$isLastMessage) {
            return $this->chatReturn(false, []);
        }

        // 通过 message Id 获取查询历史的消息
        $msgList = ChatGroupHistoryService::getTextHistoryMsgBySessionId($this->lastMsgInfo->sessionId);

        Log::info('BOT_AI:chat', [
            '$this->lastMsgInfo->sessionId' => $this->lastMsgInfo->sessionId
        ]);

        $message = $aiBot->handelData($msgList);

        return $this->chatReturn(true, $aiBot->chat($message));
    }

    /**
     * 聊天返回
     *
     * @param bool $isChat
     * @param array $data
     * @return array
     */
    public function chatReturn(bool $isChat, array $data): array
    {
        return [
            'isChat' => $isChat,
            'data'   => $data
        ];
    }

    /**
     * 呼叫人工
     *
     * @param $shopId
     * @param $groupId
     * @return void
     */
    public static function callServe($shopId, $groupId)
    {
        try {
            ChatGroupSessionService::callServe($shopId, $groupId, false);
        } catch (Exception $exception) {

        }
    }

    /**
     * 常见问题回复
     *
     * @param Model $answer 答案
     * @param int $groupId 群 ID
     * @param bool $isAiAnswer 是否 AI 发送答案
     * @return void
     * @throws Exception
     */
    public static function sendQuestionAnswer(Model $answer, int $groupId, bool $isAiAnswer = false)
    {
        $data = ChatGroupFAQModel::getFAQtDialogContent($answer->answer, $answer->indexNumber, $isAiAnswer);

        // 发送消息
        ChatGroupAiChatService::aiSendMsg($groupId, ChatGroupHistoryModel::TYPE_DIALOG, $data);

        // 清空会话状态
        ChatGroupAiChatService::clearAiHistory($groupId);

        // 消息hook
        ChatGroupAiChatService::updateHook();
    }

    /**
     * AI 发消息
     *
     * @param int $groupId
     * @param string $type
     * @param $msg
     * @return void
     * @throws Exception
     */
    public static function aiSendMsg(int $groupId, string $type, $msg)
    {
        dispatch(function () use ($groupId, $type, $msg) {
            (new ChatGroupStructService($groupId))
                ->sendMsgStruct(ChatGroupUserModel::KUA_XIAO_FU_USER_ID, '', $type, $msg, 0, 0,
                    ChatGroupHistoryModel::IS_SEND_AI_YES)
                ->send();
        });

//        ChatGroupAiChatService::clearAiHistory($groupId);

        // 走默认队列去吧, 好像自己调用自己队列会报错
//            ->onQueue(self::QUEUE_NAME);
    }

    /**
     * 清空 AI 会话
     *
     * @param int $groupId
     * @return void
     */
    public static function clearAiHistory(int $groupId)
    {
        dispatch(function () use ($groupId) {

            $sessionId = (int)ChatGroupSessionModel::query()
                                                   ->where('groupId', $groupId)
                                                   ->orderByDesc('id')
                                                   ->value('id');
            if (!$sessionId) {
                return;
            }

            // 清空历史
            ChatGroupHistoryModel::query()
                                 ->where('sessionId', $sessionId)
                                 ->where('isSendAi', ChatGroupHistoryModel::IS_SEND_AI_YES)
                                 ->update(['isSendAi' => ChatGroupHistoryModel::IS_SEND_AI_NO]);
        })->delay(2);
    }

    public static function updateHook()
    {

    }

}
